/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <ctype.h>
#include "fmt_args_parser.h"

FMTArgsPaser::FMT_TOKEN_TYPE FMTArgsPaser::GetNextToken()
{
	if (posBeingParsed == nullptr) {
		return UNKNOWN_FMT;
	}
	if (*posBeingParsed == '\0') {
		return END_OF_FMT;
	}
    while (isspace((unsigned char)(*posBeingParsed))) {
        ++posBeingParsed;
    }
	if (*posBeingParsed == 'I') {
		++posBeingParsed;
		if (*posBeingParsed == '3' && *(posBeingParsed + 1) == '2') {
			posBeingParsed += 2;
			return INT32_FMT;
		}
		else if (*posBeingParsed == '6' && *(posBeingParsed + 1) == '4') {
			posBeingParsed += 2;
			return INT64_FMT;
		}
		else {
			return INT32_FMT;
		}
	} else if (*posBeingParsed == 'U') {
		++posBeingParsed;
		if (*posBeingParsed == '3' && *(posBeingParsed + 1) == '2') {
			posBeingParsed += 2;
			return UINT32_FMT;
		}
		else if (*posBeingParsed == '6' && *(posBeingParsed + 1) == '4') {
			posBeingParsed += 2;
			return UINT64_FMT;
		}
		else {
			return UINT32_FMT;
		}
	} else if (*posBeingParsed == 'f') {
		++posBeingParsed;
		return DOUBLE_FMT;
	} else if (*posBeingParsed == 's') {
		++posBeingParsed;
		return LOWER_S_FMT;
	} else if (*posBeingParsed == 'S') {
		++posBeingParsed;
		return UPPER_S_FMT;
	} else if (*posBeingParsed == 'v') {
		++posBeingParsed;
		return NAPI_VALUE_FMT;
	} else {
		++posBeingParsed;
		return UNKNOWN_FMT;
	}
}

int FMTArgsPaser::Parse(std::vector<FMT_TOKEN_TYPE>& fmt_vec)
{
	fmt_vec.clear();
    this->posBeingParsed = this->strToParse;
	FMT_TOKEN_TYPE token_type;
	while ((token_type = GetNextToken()) != END_OF_FMT) {
		if (token_type == END_OF_FMT) {
			break;
		}
		if (token_type == UNKNOWN_FMT) {
			return -1;
		}
		fmt_vec.push_back(token_type);
	}
	return 0;
}